package com.topscomm.mpm.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.topscomm.mpm.pojo.MpmProjectEntity;
import com.topscomm.mpm.pojo.MpmProjectMilepostEntity;
import com.topscomm.mpm.pojo.MpmProjectTaskEntity;
import com.topscomm.mpm.pojo.MpmProjectTaskFeedbackEntity;
import com.topscomm.mpm.service.IMpmProjectMilepostService;
import com.topscomm.mpm.service.IMpmProjectService;
import com.topscomm.mpm.service.IMpmProjectTaskService;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.pub.vo.ResponseResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @author liwanpeng
 * @version 1.0
 * @description: TODO
 * @date 2021/1/23 14:32
 */
@Service
public class MpmGanttService {
    @Autowired
    private IMpmProjectService mpmProjectService;
    @Autowired
    private IMpmProjectMilepostService mpmProjectMilepostService;
    @Autowired
    private IMpmProjectTaskService mpmProjectTaskService;
    /**
     * @description: 获取甘特图信息
     * @param: projectId
     * @return: com.topscomm.pub.vo.ResponseResult<java.lang.Object>
     * @author Administrator
     * @date: 2021/1/23 14:34
     */
    public ResponseResult<Object> getGanttInfo(long projectId){
        Map<String, Object> result = new HashMap<>();
        List<Map<String, Object>> resultForData = new ArrayList<>();
        List<Map<String, Object>> resultForLink = new ArrayList<>();
        // 获取项目信息
        MpmProjectEntity mpmProjectEntity = mpmProjectService.queryById(String.valueOf(projectId));
        // 转换为甘特图需要的数据格式
        Map<String, Object> projectGantInfo =  new HashMap<>();
        projectGantInfo.put("id",projectId+"P");
        projectGantInfo.put("text",mpmProjectEntity.getProjectname());
        projectGantInfo.put("open",true);
        projectGantInfo.put("type","mpmProject");
        projectGantInfo.put("abnormalState",mpmProjectEntity.getAbnormalstate());
        projectGantInfo.put("plan_start_date", DateUtil.formatDate(mpmProjectEntity.getPlanstartdate()));
        projectGantInfo.put("start_date", DateUtil.formatDate(mpmProjectEntity.getPlanstartdate()));
        projectGantInfo.put("plan_end_date",DateUtil.formatDate(mpmProjectEntity.getPlanenddate()));
        if (("2,8").contains(mpmProjectEntity.getProjectstate())) {
            projectGantInfo.put("end_date",DateUtil.formatDate(DateUtil.offsetDay(mpmProjectEntity.getActualenddate(),1)));
        } else {
            projectGantInfo.put("end_date",DateUtil.formatDate(DateUtil.offsetDay(mpmProjectEntity.getPlanenddate(),1)));
        }
        projectGantInfo.put("project_state",mpmProjectEntity.getProjectstate());
        // 计算进度：（当前时间-计划开始）/（计划结束-计划开始）
        DecimalFormat df=new DecimalFormat("0.0000");//设置保留位数
        long planDay = DateUtil.betweenDay(mpmProjectEntity.getPlanstartdate(), DateUtil.offsetDay(mpmProjectEntity.getPlanenddate(),1), false);
        long actualDay;
        if (("2,8").contains(mpmProjectEntity.getProjectstate())) {
            actualDay = DateUtil.betweenDay(mpmProjectEntity.getPlanstartdate(), DateUtil.offsetDay(mpmProjectEntity.getActualenddate(), 1), false);
        } else {
            actualDay = DateUtil.betweenDay(mpmProjectEntity.getPlanstartdate(), new Date(), false);
        }
        projectGantInfo.put("duration",planDay);
        projectGantInfo.put("progress",df.format((float)actualDay/planDay));
        resultForData.add(projectGantInfo);
        // 获取里程碑及任务信息
        StringBufferProxy whereSql = new StringBufferProxy();
        whereSql.appendSingle(" projectcode = '{0}' and enabled = 1 ",mpmProjectEntity.getProjectcode());
        List<Map<String, Object>> milepostList = mpmProjectMilepostService.queryMapByWhere(whereSql.toString(), "queryMilepostForGantt");
        // 转换为甘特图需要的数据格式
        milepostList.forEach(item->{
            Map<String, Object> milepostGantt =  new HashMap<>();// 甘特图信息
            milepostGantt.put("id", ConvertUtil.convertToLong(item.get(MpmProjectMilepostEntity.FieldOperatecode)) + "M");
            milepostGantt.put("text", ConvertUtil.convertToString(item.get(MpmProjectMilepostEntity.FieldMilepostname)));
            milepostGantt.put("parent",projectId+"P");
            Date actualFinishTime = ConvertUtil.convertToDate(item.get(MpmProjectMilepostEntity.FieldActualfinishtime)),
                    planFinishTime = ConvertUtil.convertToDate(item.get(MpmProjectMilepostEntity.FieldPlanfinishtime));
            if (ObjectUtil.isEmpty(actualFinishTime)){
                milepostGantt.put("plan_end_date", DateUtil.formatDate(DateUtil.offsetDay(planFinishTime,0)));
                milepostGantt.put("start_date", DateUtil.formatDate(DateUtil.offsetDay(planFinishTime,1)));
                milepostGantt.put("end_date", DateUtil.formatDate(DateUtil.offsetDay(planFinishTime,1)));
            }else {
                milepostGantt.put("plan_end_date", DateUtil.formatDate(DateUtil.offsetDay(planFinishTime,0)));
                milepostGantt.put("start_date", DateUtil.formatDate(DateUtil.offsetDay(actualFinishTime,1)));
                milepostGantt.put("end_date", DateUtil.formatDate(DateUtil.offsetDay(actualFinishTime,1)));
            }
            milepostGantt.put("mile_state", ConvertUtil.convertToInt(item.get(MpmProjectMilepostEntity.FieldMilepoststate)));// 里程碑及任务状态
            milepostGantt.put("type","milestone");
            // 判断是否超期
            if (new Date().getTime() > planFinishTime.getTime() && ConvertUtil.convertToInt(item.get(MpmProjectMilepostEntity.FieldEnabled)) == 1
                    && ConvertUtil.convertToInt(item.get(MpmProjectMilepostEntity.FieldMilepoststate))==0) {
                milepostGantt.put("isOverdue",true);
            }else {
                milepostGantt.put("isOverdue",false);
            }
            Map<String, Object> lineMap =  new HashMap<>();// 连接线信息
            lineMap.put("id", ConvertUtil.convertToLong(item.get(MpmProjectMilepostEntity.FieldId)) + "M");
            lineMap.put("source",projectId+"P");
            lineMap.put("target", ConvertUtil.convertToLong(item.get(MpmProjectMilepostEntity.FieldOperatecode)) + "M");
            lineMap.put("type",1);
            resultForLink.add(lineMap);
            resultForData.add(milepostGantt);
        });
        // 获取任务信息
        whereSql.clear();
        whereSql.appendSingle(" projectcode = '{0}' and enabled = 1 and state = 9 ",mpmProjectEntity.getProjectcode());
        List<Map<String, Object>> taskList = mpmProjectTaskService.queryMapByWhere(whereSql.toString(), "queryTaskForGantt");
        // 转换为甘特图需要的数据格式
        taskList.forEach(item->{
            Map<String, Object> taskGanttPlan =  new HashMap<>(); // 计划
            long id = ConvertUtil.convertToLong(item.get("id"));
            taskGanttPlan.put("id", id + "T");
            taskGanttPlan.put("text", ConvertUtil.convertToString(item.get(MpmProjectTaskEntity.FieldTaskname)));
            String milepostCode = ConvertUtil.convertToString(item.get(MpmProjectTaskEntity.FieldMilepostcode));
            taskGanttPlan.put("parent", milepostCode + "M");
            // 实际开始时间（如果任务未开始则使用计划开始时间，且将任务状态置为未开始）
            Date planStartDate = ConvertUtil.convertToDate(item.get(MpmProjectTaskEntity.FieldPlanstartdate));
            taskGanttPlan.put("plan_start_date",DateUtil.formatDate(planStartDate));// 计划开始时间
            String taskState = ConvertUtil.convertToString(item.get(MpmProjectTaskEntity.FieldTaskstate));
            taskGanttPlan.put("task_state",taskState); // 任务状态
            String taskDetail = ConvertUtil.convertToString(item.get(MpmProjectTaskEntity.FieldTaskdetail));
            taskGanttPlan.put("task_detail",taskDetail); // 任务内容
            String improvePlan = ConvertUtil.convertToString(item.get(MpmProjectTaskEntity.FieldImproveplan));
            taskGanttPlan.put("improve_plan",improvePlan); // 客户关系改善计划
            String taskFeedBackDetail = ConvertUtil.convertToString(item.get(MpmProjectTaskFeedbackEntity.FieldTaskfeedbackdetail));
            taskGanttPlan.put("task_feed_back_detail",taskFeedBackDetail); // 任务反馈内容
            String taskFeedBackSchedule = ConvertUtil.convertToString(item.get("feedbacktaskschedule"));
            taskGanttPlan.put("task_feed_back_schedule",taskFeedBackSchedule); // 任务进度
            Date submitDate = ConvertUtil.convertToDate(item.get("feedbacksubmitdate"));
            taskGanttPlan.put("submit_date",DateUtil.formatDate(submitDate)); // 反馈时间
            if ("0".equals(taskState)){
                taskGanttPlan.put("start_date", DateUtil.formatDate(planStartDate));// 使用计划开始时间
            }else {
                // 使用实际开始时间
                taskGanttPlan.put("start_date", DateUtil.formatDate(ConvertUtil.convertToDate(item.get(MpmProjectTaskEntity.FieldActualstartdate))));
            }
            // 如果任务已结束，使用实际结束时间，否则使用计划结束时间
            Date planEndDate = ConvertUtil.convertToDate(item.get(MpmProjectTaskEntity.FieldPlanenddate)),
                    actualEndDate = ConvertUtil.convertToDate(item.get(MpmProjectTaskEntity.FieldActualenddate));
            taskGanttPlan.put("plan_end_date", DateUtil.formatDate(DateUtil.offsetDay(planEndDate,0)));// 使用计划结束时间
            if ("2".equals(taskState) && actualEndDate != null){
                taskGanttPlan.put("end_date", DateUtil.formatDate(DateUtil.offsetDay(actualEndDate,1)));// 使用实际结束时间
            }else {
                taskGanttPlan.put("end_date", DateUtil.formatDate(DateUtil.offsetDay(planEndDate,1)));// 使用计划结束时间
            }
            // 判断是否超期（任务未完成，且计划完成时间小于当前时间）
            boolean isfinished = (taskState.equals("2"));
            if (new Date().getTime() > planEndDate.getTime() && !isfinished){
                taskGanttPlan.put("isOverdue",true);
            } else if (isfinished && actualEndDate != null && actualEndDate.getTime() > planEndDate.getTime()) {
                taskGanttPlan.put("isOverdue",true);
            } else {
                taskGanttPlan.put("isOverdue",false);
            }
            BigDecimal taskSchedule = ConvertUtil.convertToBigDecimal(item.get(MpmProjectTaskEntity.FieldTaskschedule));
            taskGanttPlan.put("progress", df.format(taskSchedule.divide(new BigDecimal(100)).doubleValue()));
            taskGanttPlan.put("type","mpmTask");
            Map<String, Object> lineMap =  new HashMap<>();// 连接线信息
            lineMap.put("id", id);
            lineMap.put("source", id + "T");
            lineMap.put("target", milepostCode + "M");
            lineMap.put("type",0);
//            resultForLink.add(lineMap);
            // 任务责任人
            taskGanttPlan.put("responsiblename", item.get("responsible"));
            resultForData.add(taskGanttPlan);
        });
        result.put("data",resultForData);
        result.put("links",resultForLink);
        return ResponseResult.ok(result);
    }
}
